home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 10
/
AACD 10.iso
/
AACD
/
Games
/
MAME
/
src
/
vidhrdw
/
tecmo.c
< prev
next >
Wrap
C/C++ Source or Header
|
2000-05-04
|
10KB
|
414 lines
/***************************************************************************
video hardware for Tecmo games
***************************************************************************/
#include "driver.h"
#include "vidhrdw/generic.h"
unsigned char *tecmo_videoram,*tecmo_colorram;
unsigned char *tecmo_videoram2,*tecmo_colorram2;
unsigned char *tecmo_scroll;
size_t tecmo_videoram2_size;
static unsigned char *dirtybuffer2;
static struct osd_bitmap *tmpbitmap2,*tmpbitmap3;
static int video_type = 0;
/*
video_type is used to distinguish Rygar, Silkworm and Gemini Wing.
This is needed because there is a difference in the tile and sprite indexing.
*/
/***************************************************************************
Start the video hardware emulation.
***************************************************************************/
int tecmo_vh_start(void)
{
if (generic_vh_start()) return 1;
if ((dirtybuffer2 = malloc(videoram_size)) == 0)
{
generic_vh_stop();
return 1;
}
memset(dirtybuffer2,1,videoram_size);
/* the background area is twice as wide as the screen */
if ((tmpbitmap2 = osd_new_bitmap(2*Machine->drv->screen_width,Machine->drv->screen_height,Machine->scrbitmap->depth)) == 0)
{
free(dirtybuffer2);
generic_vh_stop();
return 1;
}
if ((tmpbitmap3 = osd_new_bitmap(2*Machine->drv->screen_width,Machine->drv->screen_height,Machine->scrbitmap->depth)) == 0)
{
osd_free_bitmap(tmpbitmap2);
free(dirtybuffer2);
generic_vh_stop();
return 1;
}
/* 0x100 is the background color */
palette_transparent_color = 0x100;
return 0;
}
int rygar_vh_start(void)
{
video_type = 0;
return tecmo_vh_start();
}
int silkworm_vh_start(void)
{
video_type = 1;
return tecmo_vh_start();
}
int gemini_vh_start(void)
{
video_type = 2;
return tecmo_vh_start();
}
/***************************************************************************
Stop the video hardware emulation.
***************************************************************************/
void tecmo_vh_stop(void){
osd_free_bitmap(tmpbitmap3);
osd_free_bitmap(tmpbitmap2);
free(dirtybuffer2);
generic_vh_stop();
}
WRITE_HANDLER( tecmo_videoram_w )
{
if (tecmo_videoram[offset] != data)
{
dirtybuffer2[offset] = 1;
tecmo_videoram[offset] = data;
}
}
WRITE_HANDLER( tecmo_colorram_w )
{
if (tecmo_colorram[offset] != data)
{
dirtybuffer2[offset] = 1;
tecmo_colorram[offset] = data;
}
}
/***************************************************************************
Draw the game screen in the given osd_bitmap.
Do NOT call osd_update_display() from this function, it will be called by
the main emulation engine.
***************************************************************************/
void tecmo_draw_sprites( struct osd_bitmap *bitmap, int priority )
{
int offs;
/* draw all visible sprites of specified priority */
for (offs = 0;offs < spriteram_size;offs += 8)
{
int flags = spriteram[offs+3];
if( (flags>>6) == priority )
{
int bank = spriteram[offs+0];
if( bank & 4 )
{ /* visible */
int which = spriteram[offs+1];
int code;
int size = (spriteram[offs + 2] & 3);
/* 0 = 8x8 1 = 16x16 2 = 32x32 3 = 64x64 */
if (size == 3) continue; /* not used by these games */
if( video_type != 0)
code = (which) + ((bank&0xf8)<<5); /* silkworm */
else
code = (which)+((bank&0xf0)<<4); /* rygar */
if (size == 1) code >>= 2;
else if (size == 2) code >>= 4;
drawgfx(bitmap,Machine->gfx[size+1],
code,
flags&0xf, /* color */
bank&1, /* flipx */
bank&2, /* flipy */
spriteram[offs + 5] - ((flags & 0x10) << 4), /* sx */
spriteram[offs + 4] - ((flags & 0x20) << 3), /* sy */
&Machine->drv->visible_area,
priority == 3 ? TRANSPARENCY_THROUGH : TRANSPARENCY_PEN,
priority == 3 ? palette_transparent_pen : 0);
}
}
}
}
void tecmo_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
{
int offs;
palette_init_used_colors();
{
int color,code,i;
int colmask[16];
int pal_base;
pal_base = Machine->drv->gfxdecodeinfo[5].color_codes_start;
for (color = 0;color < 16;color++) colmask[color] = 0;
for (offs = videoram_size - 1;offs >= 0;offs--)
{
if (video_type == 2) /* Gemini Wing */
{
code = videoram[offs] + 16 * (colorram[offs] & 0x70);
color = colorram[offs] & 0x0f;
}
else
{
code = videoram[offs] + 256 * (colorram[offs] & 0x07),
color = colorram[offs] >> 4;
}
colmask[color] |= Machine->gfx[5]->pen_usage[code];
}
for (color = 0;color < 16;color++)
{
if (colmask[color] & (1 << 0))
palette_used_colors[pal_base + 16 * color] = PALETTE_COLOR_TRANSPARENT;
for (i = 1;i < 16;i++)
{
if (colmask[color] & (1 << i))
palette_used_colors[pal_base + 16 * color + i] = PALETTE_COLOR_USED;
}
}
pal_base = Machine->drv->gfxdecodeinfo[4].color_codes_start;
for (color = 0;color < 16;color++) colmask[color] = 0;
for (offs = videoram_size - 1;offs >= 0;offs--)
{
if (video_type == 2) /* Gemini Wing */
{
code = tecmo_videoram[offs] + 16 * (tecmo_colorram[offs] & 0x70);
color = tecmo_colorram[offs] & 0x0f;
}
else
{
code = tecmo_videoram[offs] + 256 * (tecmo_colorram[offs] & 0x07),
color = tecmo_colorram[offs] >> 4;
}
colmask[color] |= Machine->gfx[4]->pen_usage[code];
}
for (color = 0;color < 16;color++)
{
if (colmask[color] & (1 << 0))
palette_used_colors[pal_base + 16 * color] = PALETTE_COLOR_TRANSPARENT;
for (i = 1;i < 16;i++)
{
if (colmask[color] & (1 << i))
palette_used_colors[pal_base + 16 * color + i] = PALETTE_COLOR_USED;
}
}
pal_base = Machine->drv->gfxdecodeinfo[1].color_codes_start;
for (color = 0;color < 16;color++) colmask[color] = 0;
for (offs = 0;offs < spriteram_size;offs += 8)
{
int flags = spriteram[offs+3];
int bank = spriteram[offs+0];
if( bank & 4 )
{ /* visible */
int which = spriteram[offs+1];
int size = (spriteram[offs + 2] & 3);
/* 0 = 8x8 1 = 16x16 2 = 32x32 3 = 64x64 */
if (size == 3) continue; /* not used by these games */
if( video_type != 0 )
code = (which) + ((bank&0xf8)<<5); /* silkworm */
else
code = (which)+((bank&0xf0)<<4); /* rygar */
if (size == 1) code >>= 2;
else if (size == 2) code >>= 4;
color = flags&0xf;
colmask[color] |= Machine->gfx[size+1]->pen_usage[code];
}
}
for (color = 0;color < 16;color++)
{
if (colmask[color] & (1 << 0))
palette_used_colors[pal_base + 16 * color] = PALETTE_COLOR_TRANSPARENT;
for (i = 1;i < 16;i++)
{
if (colmask[color] & (1 << i))
palette_used_colors[pal_base + 16 * color + i] = PALETTE_COLOR_USED;
}
}
pal_base = Machine->drv->gfxdecodeinfo[0].color_codes_start;
for (color = 0;color < 16;color++) colmask[color] = 0;
for (offs = tecmo_videoram2_size - 1;offs >= 0;offs--)
{
code = tecmo_videoram2[offs] + ((tecmo_colorram2[offs] & 0x03) << 8);
color = tecmo_colorram2[offs] >> 4;
colmask[color] |= Machine->gfx[0]->pen_usage[code];
}
for (color = 0;color < 16;color++)
{
for (i = 1;i < 16;i++)
{
if (colmask[color] & (1 << i))
palette_used_colors[pal_base + 16 * color + i] = PALETTE_COLOR_USED;
}
}
}
if (palette_recalc())
{
memset(dirtybuffer,1,videoram_size);
memset(dirtybuffer2,1,videoram_size);
}
/* draw the background. */
for (offs = videoram_size - 1;offs >= 0;offs--)
{
if (dirtybuffer[offs])
{
int code,color,sx,sy;
if (video_type == 2) /* Gemini Wing */
{
code = videoram[offs] + 16 * (colorram[offs] & 0x70);
color = colorram[offs] & 0x0f;
}
else
{
code = videoram[offs] + 256 * (colorram[offs] & 0x07),
color = colorram[offs] >> 4;
}
sx = offs % 32;
sy = offs / 32;
drawgfx(tmpbitmap2,Machine->gfx[5],
code,
color,
0,0,
16*sx,16*sy,
0,TRANSPARENCY_NONE,0);
dirtybuffer[offs] = 0;
}
if (dirtybuffer2[offs])
{
int code,color,sx,sy;
if (video_type == 2) /* Gemini Wing */
{
code = tecmo_videoram[offs] + 16 * (tecmo_colorram[offs] & 0x70);
color = tecmo_colorram[offs] & 0x0f;
}
else
{
code = tecmo_videoram[offs] + 256 * (tecmo_colorram[offs] & 0x07),
color = tecmo_colorram[offs] >> 4;
}
sx = offs % 32;
sy = offs / 32;
drawgfx(tmpbitmap3,Machine->gfx[4],
code,
color,
0,0,
16*sx,16*sy,
0,TRANSPARENCY_NONE,0);
}
dirtybuffer2[offs] = 0;
}
/* copy the temporary bitmap to the screen */
{
int scrollx,scrolly;
/* draw background tiles */
scrollx = -tecmo_scroll[3] - 256 * (tecmo_scroll[4] & 1) - 48;
scrolly = -tecmo_scroll[5];
copyscrollbitmap(bitmap,tmpbitmap2,1,&scrollx,1,&scrolly,
&Machine->drv->visible_area,TRANSPARENCY_NONE,0);
/* sprites will be drawn with TRANSPARENCY_THROUGH and appear behind the background */
tecmo_draw_sprites( bitmap,3 ); /* this should never draw anything, but just in case... */
tecmo_draw_sprites( bitmap,2 );
/* draw foreground tiles */
scrollx = -tecmo_scroll[0] - 256 * (tecmo_scroll[1] & 1) - 48;
scrolly = -tecmo_scroll[2];
copyscrollbitmap(bitmap,tmpbitmap3,1,&scrollx,1,&scrolly,
&Machine->drv->visible_area,TRANSPARENCY_PEN,palette_transparent_pen);
}
tecmo_draw_sprites( bitmap,1 );
/* draw the frontmost playfield. They are characters, but draw them as sprites */
for (offs = tecmo_videoram2_size - 1;offs >= 0;offs--)
{
int sx = offs % 32;
int sy = offs / 32;
drawgfx(bitmap,Machine->gfx[0],
tecmo_videoram2[offs] + ((tecmo_colorram2[offs] & 0x03) << 8),
tecmo_colorram2[offs] >> 4,
0,0,
8*sx,8*sy,
&Machine->drv->visible_area,TRANSPARENCY_PEN,0);
}
tecmo_draw_sprites( bitmap,0 );
}